#pragma once

#include "pch.h"

/**
 * @file MFCPaintor.h
 * @author xingyifan
 * @date 2022-12-09 14:24
 *
 * @description: 绘制器
 */

class Paintor
{
public:
    Paintor(CFrameWnd *pWnd) : m_pWnd(pWnd), m_oldBmp(nullptr),
                               m_pen(nullptr), m_oldPen(nullptr), m_brush(nullptr), m_oldBrush(nullptr) {}

    /**
     * @file MFCPaintor.h
     * @author xingyifan
     * @date 2022-12-09 14:27
     *
     * @description: 开启双缓冲绘图，返回新的绘图 DC
     */

    CDC &BeginPaint(CDC &dc)
    {
        // 获取客户区大小
        CRect winRect;
        m_pWnd->GetClientRect(&winRect);

        // 创建内存 dc
        m_memdc.CreateCompatibleDC(&dc);

        // 创建兼容的位图
        m_bitmap.CreateBitmap(winRect.Width(), winRect.Height(), 1, 32, 0);

        // 选入位图，并填充背景
        m_oldBmp = m_memdc.SelectObject(&m_bitmap);
        m_memdc.FillSolidRect(winRect, RGB(255, 255, 255));

        return m_memdc;
    }

    /**
     * @file MFCPaintor.h
     * @author xingyifan
     * @date 2022-12-09 14:28
     *
     * @description: 结束双缓冲绘图
     */

    void EndPaint(CDC &dc)
    {
        // 获取客户区大小
        CRect winRect;
        m_pWnd->GetClientRect(&winRect);

        // 将内存 dc 中的图像输出到当前 dc
        dc.BitBlt(0, 0, winRect.Width(), winRect.Height(), &m_memdc, 0, 0, SRCCOPY);

        // 选入旧的位图
        m_memdc.SelectObject(m_oldBmp);

        // 释放资源
        m_bitmap.DeleteObject();
        m_memdc.DeleteDC();
    }

    /**
     * @file MFCPaintor.h
     * @author xingyifan
     * @date 2022-12-09 14:28
     *
     * @description: 画笔画刷操作
     */

    void CreatePen(CDC *dc, int nPenStyle, int nWidth, COLORREF nColor)
    {
        // 如果之前有画笔就先删除
        if (m_pen != nullptr)
            DeletePen(dc);

        m_pen = new CPen(nPenStyle, nWidth, nColor);
        m_oldPen = dc->SelectObject(m_pen);
    }

    void CreateBrush(CDC *dc, COLORREF nColor)
    {
        // 如果之前有画刷就先删除
        if (m_brush != nullptr)
            DeleteBrush(dc);

        m_brush = new CBrush(nColor);
        m_oldBrush = dc->SelectObject(m_brush);
    }

    void DeletePen(CDC *dc)
    {
        dc->SelectObject(m_oldPen);
        m_pen->DeleteObject();
        m_pen = nullptr;
        m_oldPen = nullptr;
    }

    void DeleteBrush(CDC *dc)
    {
        dc->SelectObject(m_oldBrush);
        m_brush->DeleteObject();
        m_brush = nullptr;
        m_oldBrush = nullptr;
    }

    // 最后只需要调用 Delete 即可结束
    void Delete(CDC *dc)
    {
        if (m_brush != nullptr)
            DeleteBrush(dc);
        if (m_pen != nullptr)
            DeletePen(dc);
    }

public:
    CFrameWnd *m_pWnd;  // 绘图框架
    CDC m_memdc;        // 内存 dc
    CBitmap m_bitmap;   // 当前位图
    CBitmap *m_oldBmp;  // 旧位图
    CPen *m_oldPen;     // 保留旧画笔
    CPen *m_pen;        // 新画笔
    CBrush *m_oldBrush; // 旧画刷
    CBrush *m_brush;    // 新画刷
};